package socketmvc.core.util;

import socketmvc.core.exception.CommonIOException;
import socketmvc.core.exception.SockFileIOException;
import socketmvc.core.packets.biz.SockFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * Byte工具集
 * @author xueyanjun
 */
public class BytesUtils {

    /**
     * int转byte数组
     * 高字节序
     * @param integer int
     * @return bytes
     */
    public static byte[] int2Bytes(int integer)
    {
        byte[] bytes=new byte[4];
        bytes[3]= (byte)(integer>>24);
        bytes[2]= (byte)(integer>>16);
        bytes[1]= (byte)(integer>>8);
        bytes[0]= (byte)integer;

        return bytes;
    }

    /**
     * bytes 转 int
     * 高字节序
     * @param bytes 字节数组
     * @return int
     */
    public static int bytes2Int(byte[] bytes)
    {
        //如果不与0xff进行按位与操作，转换结果将出错，有兴趣的同学可以试一下。
        int int1=bytes[0]&0xff;
        int int2=(bytes[1]&0xff)<<8;
        int int3=(bytes[2]&0xff)<<16;
        int int4=(bytes[3]&0xff)<<24;
        return int1|int2|int3|int4;
    }

    /**
     * bytes 转 string
     * @param bytes 字节数组
     * @return string
     */
    public static String bytesToString(byte[] bytes){
        return new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * string 转byte数组
     * @param str string
     * @return bytes
     */
    public static byte[] stringToBytes(String str){
        return str.getBytes(StandardCharsets.UTF_8);
    }


    public static String bytesToHexString(byte[] bytes){
        StringBuilder stringBuilder = new StringBuilder();
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        for (byte b : bytes) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static byte[] hexStringToBytes(String hexStr) {
        if (hexStr == null || hexStr.equals("")) {
            return null;
        }
        hexStr = hexStr.toUpperCase();
        int length = hexStr.length() / 2;
        char[] hexChars = hexStr.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }


    public static byte charToByte(char c) {
        return (byte)"0123456789ABCDEF".indexOf(c);
    }


    /**
     * 使用gzip压缩内容
     * @param data 内容
     * @return 压缩后的内容
     * @throws CommonIOException io异常
     */
    public static byte[] compressGzip(byte[] data) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (GZIPOutputStream gzip = new GZIPOutputStream(bos,1024)) {
            gzip.write(data);
        }catch (IOException e){
            throw new CommonIOException(e);
        }
        return bos.toByteArray();
    }

    /**
     * 使用gzip解压缩内容
     * @param data 内容
     * @return 解压缩后的内容
     * @throws CommonIOException io异常
     */
    public static byte[] decompressGzip(byte[] data) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ByteArrayInputStream bis = new ByteArrayInputStream(data);
        try (GZIPInputStream gzip = new GZIPInputStream(bis)) {
            byte[] buffer = new byte[2048];
            int len;
            while ((len = gzip.read(buffer)) > 0) {
                bos.write(buffer, 0, len);
            }
        }catch (IOException e){
            throw new CommonIOException(e);
        }
        return bos.toByteArray();
    }

}
